<template>
    <div class="paper">
      <!-- 答题卡 -->
      <div class="paper-left">
        <el-card shadow="never" class="paper-left-top">
          <!-- <el-avatar size="large"/> -->
          <span class="paper-left-top-username">
            {{ user.name }} / {{ user.orgName }}
          </span>
          <div class="paper-left-top-statis">
            <div>
              <Iconfont
                icon="icon-jiangbei"
                :size="20"
                color="#F6961E;"
                :width="30"
                :height="30"
                :radius="5"
                background-color="#FDF3E7"
              />
              <span class="paper-left-top-statis-value">{{ questionNum }}道</span>
  
              <span class="paper-left-top-statis-txt">试题数量</span>
            </div>
            <div>
              <Iconfont
                icon="icon-approval-fulll"
                :size="20"
                color="#05CAC1;"
                :width="30"
                :height="30"
                :radius="5"
                background-color="#E3F3FF"
              />
              <span class="paper-left-top-statis-value"
                >{{ questionErrNum }}道</span
              >
              <span class="paper-left-top-statis-txt">错误题数</span>
            </div>
            <div>
              <Iconfont
                icon="icon-shijianxuanzhong"
                :size="20"
                color="#F6961E;"
                :width="30"
                :height="30"
                :radius="5"
                background-color="#FDF3E7"
              />
              <span class="paper-left-top-statis-value"
                >{{ diffMinute }}分钟</span
              >
              <span class="paper-left-top-statis-txt">答题用时</span>
            </div>
          </div>
          <fontSet />
          <el-button type="primary" plain @click="$router.go(-1)">返回</el-button>
        </el-card>
        <el-card shadow="never" class="paper-left-bottom" style="background-color: #fafafa;">
          <el-divider> 答题卡 </el-divider>
          <el-scrollbar height="calc(100vh - 340px)">
            <template v-for="(questionId, index) in exer.questionIds">
              <el-button
                :type="errMark(index).type"
                :plain="errMark(index).plain"
                @click="questionView(index)"
                >{{ index + 1 }}</el-button
              >
            </template>
          </el-scrollbar>
        </el-card>
      </div>
      <!-- 试卷 -->
      <el-card shadow="never" style="background-color: #fafafa;" class="paper-right">
        <!-- 选项 -->
        <div class="paper-right-opt">
          <el-button
            link
            :disabled="curQuestion.index <= 0"
            @click="next(false)"
            class="myButton"
            >{{ `<<上一题` }}</el-button
          >
          <el-button
            link
            @click="next(true)"
            class="myButton"
            >{{ `下一题>>` }}</el-button
          >
          <el-checkbox v-model="exer.answerShow" label="背题"></el-checkbox>
          <el-checkbox v-model="exer.randShow" label="随机"></el-checkbox>
          <span
            v-if="curQuestion.question.collectFlag"
            class="heartContent"
            @click="favClick"
          >
            <HeartFilled class="heart" />已收藏
          </span>
          <span v-else class="heartContent" @click="favClick">
            <HeartOutlined class="heart" />未收藏
          </span>
          <FeedbackComponent
          feedbackTitle="题目纠错"
          v-if="curQuestion.question.id"
          :questionId="curQuestion.question.id"
        />
        </div>
        <el-divider />
        <!-- 试题 -->
        <QuestionVue
          v-if="curQuestion.index >= 0"
          :no="curQuestion.index + 1"
          :type="curQuestion.question.type"
          :markType="curQuestion.question.markType"
          :title="curQuestion.question.title"
          :score="curQuestion.question.score"
          :answers="curQuestion.question.answers"
          :userScore="curQuestion.question.userScore"
          :userAnswers="curQuestion.question.userAnswers"
          :options="curQuestion.question.options"
          :editable="!exer.answerShow && curQuestion.question.userScore == null"
          @change="(answers: string[]) => {
                      exer.lastTime = new Date() // 答题就更新时间
                      curQuestion.question.userAnswers = answers
                      if (curQuestion.question.type === 1 || curQuestion.question.type === 4) {// 单选或判断，选完答案，自动下一题
                          next(true)
                      }
                  }"
          :user-answer-show="!exer.answerShow"
          :errShow="!exer.answerShow && curQuestion.question.userScore != null"
        >
          <template #bottom-right>
            <el-tooltip
              placement="top"
              effect="light"
              :content="answerFormat(curQuestion.question)"
              popper-class="popper-class"
            >
              <el-button type="success" size="small">标准答案</el-button>
            </el-tooltip>
          </template>
        </QuestionVue>
        <!-- 评论 -->
      </el-card>
    </div>
  </template>
  <script lang="ts" setup>
  import http from "@/request";
  import {
    computed,
    onMounted,
    onUnmounted,
    reactive,
    ref,
    watch,
    watchEffect,
  } from "vue";
  import QuestionVue from "@/components/question/Question.vue";
  import FeedbackComponent from "@/components/feedback.vue";
  import _ from "lodash";
  import { useRouter, useRoute } from "vue-router";
  import { ElMessage, ElMessageBox, type Action } from "element-plus";
  import { Download, Star } from "@element-plus/icons-vue";
  import { HeartFilled, HeartOutlined } from "@ant-design/icons-vue";
  import type { Question } from "@/stores/exam";
  import dayjs from "dayjs";
  import CountDown from "@/components/CountDown.vue";
  import { useUserStore } from "@/stores/user";
  import fontSet from "@/components/fontSet.vue";
  
  // 定义变量
  const userStore = useUserStore();
  const route = useRoute();
  const router = useRouter();
  const exer = reactive({
    // 练习信息
    id: 0, // 练习ID
    startTime: null as unknown, // 开始时间
    endTime: null as unknown, // 结束时间
    rmkState: 2, // 评论状态（1：是；2：否）
    questionIds: [] as number[], // 试题列表
    answerShow: false, // 标准答案显示
    randShow: false, // 乱序显示
    rmkShow: false, // 评论显示
    firstTime: new Date(), // 第一次进入时间
    lastTime: new Date(), // 最后一次答题时间
    color: "", // 倒计时颜色
  });
  const curQuestion = reactive({
    // 当前试题
    index: -1, // 索引
    question: {} as Question, // 内容
    cache: {} as { [questionId: number]: Question }, // 缓存
  });
  const user = reactive({
    // 用户信息
    name: "", // 姓名
    orgName: "", // 机构名称
  });
  
  // 组件挂载完成后，执行如下方法
  onMounted(async () => {
    // 隐藏页头信息（模拟全屏）
  
    // 获取机构信息
    let {
      data: { data: data2 },
    } = await http.post("user/get", {});
    user.name = data2.name;
    user.orgName = data2.orgName;
  
    // 获取我的练习
    exer.id = parseInt(route.params.exerId as string);
  
    let {
      data: { data },
    } = await http.post("myExer/questionList", { questionTypeId: exer.id });
    data.userAnswers = [];
    data.userScore = null;
    exer.questionIds.push(...data);
  
    if (exer.questionIds.length) {
      // 显示第一个
      questionView(0);
    }
  });
  
  // 监听属性
  watch(
    () => exer.randShow,
    async (n, o) => {
      // 随机和顺序，同一个索引不是同一个题
      questionView(curQuestion.index);
    }
  );
  
  const favClick = async () => {
    let questionIds = curQuestion.question.id;
    let currentQuestionId = curQuestion.question?.collectFlag;
  
    //如果为真，添加收藏
    if (!currentQuestionId) {
      let data1 = await http.post("myCollect/addAndUpdate", {
        questionId: questionIds,
      });
      if (data1.data.code == 200) {
        curQuestion.question.collectFlag = 1;
      }
    } else {
      let data2= await http.post("myCollect/delByQuestionId", {
        questionId: questionIds,
      });
      if (data2.data.code == 200) {
        curQuestion.question.collectFlag = 0;
      }
    }
  };
  // 计算属性
  const questionIdsOfShuffle = computed(() => {
    // 点随机的时候用
    return _.shuffle(exer.questionIds);
  });
  const questionNum = computed(() => {
    // 试题数量
    return exer.questionIds.length;
  });
  const questionErrNum = computed(() => {
    // 试题错误数量
    return exer.questionIds.reduce((total, questionId) => {
      let question = curQuestion.cache[questionId];
      if (
        question &&
        (question.type === 1 || question.type === 2 || question.type === 4)
      ) {
        // 如果是单选多选判断
        if (question.userScore != null && question.userScore !== question.score) {
          // 答过题且不是全对
          total++; // 错误数加一
        }
      }
      return total;
    }, 0);
  });
  const diffMinute = computed(() => {
    // 答题时长（分钟数）
    return dayjs(exer.lastTime).diff(exer.firstTime, "minute") + 1;
  });
  
  // 组件卸载完成后，执行如下方法
  onUnmounted(() => {});
  
  /**
   * 试题查阅
   *
   * v1.0 zhanghc 2023-04-27 12:05:09
   * @param {*} index 试题列表索引
   * @return {*}
   */
  async function questionView(index: number) {
    let questionId = exer.randShow
      ? questionIdsOfShuffle.value[index]
      : exer.questionIds[index];
    if (curQuestion.cache[questionId]) {
      curQuestion.index = index;
      curQuestion.question = curQuestion.cache[questionId];
    } else {
      let {
        data: { data: data },
      } = await http.post("myExer/question", { exerId: exer.id, questionId });
      data.userAnswers = []; // 接口没有
      data.userScore = null; // 接口没有
      curQuestion.question = data;
      curQuestion.cache[questionId] = data;
  
      curQuestion.index = index;
    }
  }
  
  /**
   * 下一题
   *
   * v1.0 zhanghc 2023-04-27 16:22:00
   * @param {*} hasNext true：下一题：false:上一题
   * @return {*} void
   */
  function next(hasNext: boolean) {
    // 数据有效性校验
  
  
    // 如果是答题模式，选择错误时，标记错误
    if (!exer.answerShow) {
      if (curQuestion.question.type === 1 || curQuestion.question.type === 4) {
        // 如果是单选或判断
        if (curQuestion.question.userScore == null) {
          // 如果没打分
          if (
            curQuestion.question.userAnswers &&
            curQuestion.question.userAnswers[0]
          ) {
            // 如果有答案
            curQuestion.question.userScore = 0;
            if (
              curQuestion.question.userAnswers[0] ===
              curQuestion.question.answers[0]
            ) {
              // 打分
              curQuestion.question.userScore = curQuestion.question.score;
            }
            if (curQuestion.question.userScore === 0) {
              // 如果答错，则停留当前题，不进入下一题
              return;
            }
          }
        }
      }
      if (curQuestion.question.type === 2) {
        // 如果是多选
        if (curQuestion.question.userScore == null) {
          // 如果没打分
          if (
            curQuestion.question.userAnswers &&
            curQuestion.question.userAnswers[0]
          ) {
            // 如果有答案
            curQuestion.question.userScore = 0;
            let include = curQuestion.question.userAnswers.every(
              (userAnswer: string) =>
                curQuestion.question.answers.includes(userAnswer)
            );
            if (
              include &&
              curQuestion.question.answers.length ===
                curQuestion.question.userAnswers.length
            ) {
              // 打分
              curQuestion.question.userScore = curQuestion.question.score;
            } else if (include) {
              curQuestion.question.userScore = curQuestion.question.scores[0];
            }
  
            if (curQuestion.question.userScore < curQuestion.question.score) {
              // 如果答错，则停留当前题，不进入下一题
              return;
            }
          }
        }
      }
    }
    if (hasNext) {
      if (curQuestion.index >= exer.questionIds.length - 1) {
        ElMessage.success("最后一题");
        return;
      }
    }
    if (!hasNext) {
      if (curQuestion.index < 0) {
        ElMessage.success("第一题");
        return;
      }
    }
    // 下一题
    if (hasNext) {
      questionView(curQuestion.index + 1);
    } else {
      questionView(curQuestion.index - 1);
    }
  }
  
  /**
   * 答案格式化显示
   *
   * v1.0 zhanghc 2023-04-27 14:45:00
   * @param {*} question 试题
   * @return {*} void
   */
  function answerFormat(question: Question) {
    if (
      question.type === 1 || // 单选
      question.type === 4 || // 判断
      (question.type === 5 && question.markType === 2)
    ) {
      // 主观问答
      return (
        question.answers &&
        question.answers[0] &&
        question.answers[0].replaceAll("\n", "<br/>")
      );
    }
    if (question.type === 2) {
      // 多选
      return question.answers?.toString().replaceAll(",", "");
    }
  
    if (
      question.type === 3 || // 填空
      (question.type === 5 && question.markType === 1)
    ) {
      // 客观问答
      let answerFormat = "";
      question.answers?.forEach((answer: string, index: number) => {
        answerFormat += `${question.type === 3 ? "填空" : "关键词"}${
          index + 1
        }：${answer.replaceAll("\n", "、")}<br/>`;
      });
  
      return answerFormat;
    }
  }
  
  /**
   * 错误标记
   *
   * v1.0 zhanghc 2023-04-27 14:45:00
   * @param {*} index 试题列表索引
   * @return {*} Object 样式
   */
  function errMark(index: number) {
    let questionId = exer.randShow
      ? questionIdsOfShuffle.value[index]
      : exer.questionIds[index];
    let question = curQuestion.cache[questionId];
    if (!question) {
      // 如果没有查看过这道题，默认颜色
      return { type: "primary", plain: true };
    }
    if (!question.userAnswers?.length) {
      // 如果没有作答，默认颜色
      return { type: "primary", plain: true };
    }
    if (question.type === 3 || question.type === 5) {
      // 如果是填空问答，填了答案就代表做过
      if (question.userAnswers.some((userAnswer) => userAnswer.length > 0)) {
        return { type: "primary", plain: false };
      }
      return { type: "primary", plain: true };
    }
    if (question.type === 1 || question.type === 2 || question.type === 4) {
      // 如果是单选多选判断
      if (question.userScore == null) {
        // 没打分，默认颜色（作用与多选）
        return { type: "primary", plain: true };
      }
      if (question.userScore === question.score) {
        // 满分绿色
        return { type: "success", plain: false };
      }
      if (question.userScore === 0) {
        // 零分红色
        return { type: "danger", plain: false };
      }
      return { type: "warning", plain: false }; // 不满分警告色
    }
  
    return { type: "primary", plain: true };
  }
  </script>
  
  <style lang="scss" scoped>
  .paper {
    flex: 1;
    display: flex;
    margin-bottom: 10px;
    .paper-left {
      width: 324px;
      display: flex;
      flex-direction: column;
      .paper-left-top {
        margin-bottom: 10px;
        :deep(.el-card__body) {
          display: flex;
          flex-direction: column;
          align-items: center;
          padding: 20px 10px;
          .el-avatar {
            border: 2px solid var(--el-color-primary);
            margin-bottom: 10px;
          }
          .paper-left-top-username {
            margin-bottom: 15px;
            font-size: 13px;
            font-weight: bold;
            color: #333;
          }
          .paper-left-top-statis {
            display: flex;
            width: 100%;
            margin-bottom: 18px;
            div {
              flex: 1;
              margin: auto;
              .paper-left-top-statis-value {
                font-size: 12px;
                font-weight: bold;
                color: var(--el-text-color-regular);
                padding-top: 5px;
                display: block;
                text-align: center;
              }
              .paper-left-top-statis-txt {
                font-size: 14px;
                font-weight: bold;
                color: #333;
                display: block;
                text-align: center;
              }
            }
          }
          .paper-left-top-time {
            border: 1px dashed var(--el-color-primary);
            padding: 5px;
            margin-top: 20px;
            width: 100%;
            span {
              font-weight: bold;
              font-size: 14px;
              color: var(--el-color-primary);
              margin: auto;
              display: block;
              text-align: center;
            }
          }
          .el-button {
            width: 100%;
            margin-top: 10px;
            margin-left: 0px;
          }
        }
      }
  
      .paper-left-bottom {
        .el-divider--horizontal {
          margin: 15px 0px 20px 0px;
        }
        .el-button {
          height: 50px;
          width: 50px;
          padding: 0;
          border: 0;
          margin: 2px;
          font-size: 18px;
        }
        .paper-left-bottom-chapter {
          font-size: 13px;
          font-weight: bold;
          margin: 5px 0px;
          cursor: pointer;
        }
      }
    }
  
    :deep(.paper-right) {
      flex: 1;
      width: 800px;
      min-height: calc(100vh - 50px);
      margin-left: 10px;
      .question-paper {
        min-height: 200px;
      }
      .paper-right-opt {
        display: flex;
        align-items: center;
        margin: 15px 15px 0px 15px;
        padding-left: 15px;
        .el-checkbox {
          margin-left: 30px;
          margin-right: 0px;
        }
      }
      .el-divider--horizontal {
        width: initial;
        margin: 5px 20px 10px 20px;
      }
      .paper-right-my-rmk {
        display: flex;
        margin: 10px 20px;
        align-items: flex-end;
        .el-textarea__inner {
          box-shadow: initial;
        }
        .el-checkbox {
          margin: 0px 10px;
        }
      }
      .paper-right-rmk-list {
        padding: 0;
        margin: 0;
        list-style: none;
        overflow: auto;
        li {
          display: flex;
          flex-direction: column;
          min-height: 50px;
          background: var(--el-color-primary-light-9);
          margin: 10px 20px;
          padding: 10px;
          color: var(--el-text-color-regular);
          .el-text {
            margin: 0px 0px 5px 0px;
            align-self: initial;
          }
          div {
            display: flex;
            justify-content: space-between;
            align-items: baseline;
            font-size: 12px;
            .el-text {
              margin: 0px;
            }
            .iconfont {
              cursor: pointer;
              font-size: 14px;
              &:hover {
                color: var(--el-color-primary);
              }
            }
          }
        }
      }
    }
  }
  </style>
  <style lang="scss" scoped>
  .paper-right {
    :deep .myButton {
      font-size: 16px;
      color: #108ee9;
    }
    :deep .el-checkbox__label {
      font-size: 16px;
      color: #333;
    }
    :deep .el-radio__label {
      font-size: 16px;
    }
  }
  
  .popper-class {
    max-width: 800px;
  }
  .heartContent {
    margin-left: 26px;
    font-size: 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    .heart {
      margin-right: 4px;
      font-size: 18px;
      color: #f50;
    }
  }
  </style>